package com.gitee.wsl.flow.combine

import com.gitee.wsl.base.tuple
import com.gitee.wsl.flow.F
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.Flow
import kotlin.jvm.JvmName


@JvmName("flowCombine")
fun <T1, T2> Flow<T1>.combine(flow: Flow<T2>) = combine(flow) { a, b -> a to b }


fun <T1, T2> F.combine(flow: Flow<T1>, flow2: Flow<T2>) = flow.combine(flow2)


/**
 * Returns a [Flow] whose values are generated with [transform] function by combining
 * the most recently emitted values by each flow.
 */
inline fun <reified T1, reified T2, reified T3> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>
) = combine(flow,flow2,flow3){a,b,c-> tuple(a,b,c) }


/**
 * Returns a [Flow] whose values are generated with [transform] function by combining
 * the most recently emitted values by each flow.
 */
inline fun <reified T1, reified T2, reified T3, reified T4> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
)= combine(flow,flow2,flow3,flow4){a,b,c,d-> tuple(a,b,c,d) }


/**
 * Returns a [Flow] whose values are generated with [transform] function by combining
 * the most recently emitted values by each flow.
 */
inline fun <reified T1, reified T2, reified T3, reified T4, reified T5> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
)= combine(flow,flow2,flow3,flow4,flow5){a,b,c,d,e-> tuple(a,b,c,d,e) }

inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    flow6: Flow<T6>,
)= combine(flow,flow2,flow3,flow4,flow5,flow6){a,b,c,d,e,f-> tuple(a,b,c,d,e,f) }

inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6, reified T7> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    flow6: Flow<T6>,
    flow7: Flow<T7>,
)= combine(flow,flow2,flow3,flow4,flow5,flow6,flow7){a,b,c,d,e,f,g-> tuple(a,b,c,d,e,f,g) }

inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6, reified T7, reified T8> F.combine(
    flow: Flow<T1>,
    flow2: Flow<T2>,
    flow3: Flow<T3>,
    flow4: Flow<T4>,
    flow5: Flow<T5>,
    flow6: Flow<T6>,
    flow7: Flow<T7>,
    flow8: Flow<T8>,
)= combine(flow,flow2,flow3,flow4,flow5,flow6,flow7,flow8){a,b,c,d,e,f,g,h-> tuple(a,b,c,d,e,f,g,h) }

//inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6, reified T7, reified T8, reified T9> F.combine(
//    flow: Flow<T1>,
//    flow2: Flow<T2>,
//    flow3: Flow<T3>,
//    flow4: Flow<T4>,
//    flow5: Flow<T5>,
//    flow6: Flow<T6>,
//    flow7: Flow<T7>,
//    flow8: Flow<T8>,
//    flow9: Flow<T9>,
//)= combine(flow,flow2,flow3,flow4,flow5,flow6,flow7,flow8,flow9){a,b,c,d,e,f,g,h,i-> tuple(a,b,c,d,e,f,g,h,i) }
